#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <chrono>
#include "../include/Logger.h"

Logger::Logger(LogLevel level, bool consoleOutput, const std::string& logFile)
    :level(level)
    ,consoleOutput(consoleOutput)
    ,logFile(logFile)
{}

// 写日志
void Logger::log(LogLevel msgLevel, const std::string& message)
{
    if(level == LogLevel::NONE || msgLevel > level)
        return;

    std::lock_guard<std::mutex> lock(this->mutex);

    // 获取系统时间
    auto now = std::chrono::system_clock::now();
    auto now_time_t = std::chrono::system_clock::to_time_t(now);

    std::stringstream timestamp;
    std::tm timeinfo;

// 跨平台处理
#if (defined_WIN32 || defined(_WIN64))
    localtime_s(&timeinfo, &now_time_t);
#else
    localtime_r(&now_time_t, &timeinfo);
#endif
    timestamp << std::put_time(&timeinfo, "%Y-%m-%d %H:%M:%S");

    // 日志级别的字符串
    std::string levelStr;
    switch(msgLevel)
    {
    case LogLevel::ERROR:
        levelStr = "错误";
        break;
    case LogLevel::INFO:
        levelStr = "信息";
        break;
    case LogLevel::DEBUG:
        levelStr = "调试";
        break;
    default: 
        levelStr = "未知";
    }

    // 格式化日志信息
    std::stringstream logMsg;
    logMsg << "[" << timestamp.str() << "] [" << levelStr << "]" << message;
    
    // 输出到控制台
    if(consoleOutput)
    {
        if(msgLevel == LogLevel::ERROR)
        {
            std::cerr << logMsg.str() << std::endl;
        }
        else
        {
            std::cout << logMsg.str() << std::endl;
        }
    }

    // 输出到文件
    if(!logFile.empty())
    {
        try
        {
            std::ofstream file(logFile, std::ios::app);
            if(file.is_open())
            {
                file << logMsg.str() << std::endl;
            }
        }
        catch(...)
        {
            if(consoleOutput)
            {
                std::cerr << "无法写入日志" << logFile << std::endl;
            }
        }
    }
}

// 设置日志级别
void Logger::setLevel(LogLevel newLevel)
{
    this->level = newLevel;
}

// 设置日志文件
void Logger::setLogFile(const std::string& filename)
{
    std::lock_guard<std::mutex> lock(mutex);
    this->logFile = filename;
}

// 启用/禁用 控制台输出
void Logger::setConsoleOutput(bool enable)
{
    std::lock_guard<std::mutex> lock(mutex);
    this->consoleOutput = enable;
}